package com.oauth.linkedin.server;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.oauth.common.server.OAuthGwtController;
import com.oauth.common.server.beans.OAuthAccessToken;
import com.oauth.common.server.beans.OAuthRequestToken;
import com.oauth.common.server.util.OAuthRequestUtil;
import com.oauth.components.client.beans.OAuthUrl;
import com.oauth.components.client.rpc.exception.SessionExpiredException;
import com.oauth.linkedin.client.beans.LinkedinModel;
import com.oauth.linkedin.client.beans.LinkedinOAuthVerifier;
import com.oauth.linkedin.client.beans.LinkedinUser;
import com.oauth.linkedin.client.exception.LinkedinOAuthException;
import com.oauth.linkedin.client.rpc.LinkedinRemoteService;
import com.oauth.linkedin.server.beans.LinkedinRequestToken;
import com.oauth.linkedin.server.constants.LinkedinConstants;
import com.oauth.linkedin.server.service.LinkedinService;
import com.oauth.logging.OAuthLogger;

public class LinkedinGwtController extends OAuthGwtController implements LinkedinRemoteService {

	private OAuthLogger logger = OAuthLogger.getLogger(this.getClass());
	private static final long serialVersionUID = -5758464341967618224L;

	private LinkedinService mLinkedinService;

	/**
	 * @param pLinkedinService
	 *            the linkedinService to set
	 */
	@Autowired
	public void setLinkedinService(LinkedinService pLinkedinService) {
		mLinkedinService = pLinkedinService;
	}

	@Override
	public OAuthUrl getSignInUrl() throws LinkedinOAuthException {
		LinkedinRequestToken requestToken;
		try {
			requestToken = mLinkedinService.getRequestToken();
		} catch (Exception e) {
			logger.error("Error in getting request token", e);
			throw new LinkedinOAuthException();
		}
		OAuthRequestUtil.createTokenCookies(getHttpResponse(), requestToken,
				LinkedinConstants.LINKEDIN_TOKEN_COOKIE,
				LinkedinConstants.LINKEDIN_TOKEN_SECRETCOOKIE);
		OAuthUrl oauthUrl = new OAuthUrl();
		oauthUrl.setOAuthUrl(requestToken.getAuthorizeUrl());
		return oauthUrl;
	}

	public List<LinkedinUser> getConnections() throws LinkedinOAuthException {
		try {
			Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
			List<LinkedinUser> connections = mLinkedinService.getConnections(memberId);
			return connections;
		} catch (Exception e) {
			logger.error("Error in fetching scraps", e);
			throw new LinkedinOAuthException();
		}
	}

	public LinkedinModel getLinkedInData(LinkedinOAuthVerifier pOAuthVerifier)
			throws LinkedinOAuthException {
		LinkedinModel model = new LinkedinModel();

		logger.info("Entering linkedin home controller");

		Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
		try {
			OAuthAccessToken accessToken = mLinkedinService.getAccessTokenFromDB(memberId);
			if (accessToken == null) {
				/* Get request token from cookie. */
				OAuthRequestToken requestToken = OAuthRequestUtil.getOAuthTokenFromCookie(
						getHttpRequest(), LinkedinConstants.LINKEDIN_TOKEN_COOKIE,
						LinkedinConstants.LINKEDIN_TOKEN_SECRETCOOKIE);

				if (requestToken == null) {
					model.setLoginView(true);
					return model;// Go to login page, as there is no access
					// token in
					// db and no cookie.
				} else {
					accessToken = mLinkedinService.getAccessTokenFromRequestToken(requestToken,
							pOAuthVerifier.getOAuthVerifier());

					/* Store access token for future use */
					mLinkedinService.persistAccessToken(accessToken, memberId);
					deleteCookies();
				}
			}
			// finally you got the access token which is stored in db.
			LinkedinUser user = getLoggedInUserInfo();
			model.setUser(user);
			return model;
		} catch (Exception e) {
			deleteCookies();
			logger.error("Error in fetching linkedin home data", e);
			e.printStackTrace();
			throw new LinkedinOAuthException();
		}
	}

	public LinkedinUser getLoggedInUserInfo() throws Exception {
		Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
		LinkedinUser profile = mLinkedinService.getLinkedinUser(memberId);
		return profile;
	}

	private void deleteCookies() {
		OAuthRequestUtil.deleteTokenCookies(getHttpResponse(),
				LinkedinConstants.LINKEDIN_TOKEN_COOKIE,
				LinkedinConstants.LINKEDIN_TOKEN_SECRETCOOKIE);
	}

	@Override
	public List<LinkedinUser> getUpdates() throws SessionExpiredException, LinkedinOAuthException {
		Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
		try {
			return mLinkedinService.getUpdates(memberId);
		} catch (Exception e) {
			logger.error("Error in getting linkedin updates", e);
			e.printStackTrace();
			throw new LinkedinOAuthException();
		}
	}

	@Override
	public boolean updateStatus(String pText) throws SessionExpiredException,
			LinkedinOAuthException {
		try {
			Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
			mLinkedinService.updateStatus(pText, memberId);
			return true;
		} catch (Exception e) {
			logger.error("Error in fetching scraps", e);
			throw new LinkedinOAuthException();
		}

	}

}
